We are migrating the bug tracker to github Issues. This is now the preferred way to report NASM bugs.
Self-registration is disabled due to spam issue (mail gorcunov@gmail.com or hpa@zytor.com to create an account)
Two points here: 1. The documentation refers to __?NASM_HAS_IFDIRECTIVE?__ but the actual smacro seems to be missing the "HAS_" part. 2. Combining __?NASM_IFDIRECTIVE?__ with %ifdirective in the obvious way won't work on older NASM versions. This is because the %ifdirective isn't detected as a valid conditional directive so there will be one too many %endif directives. As a workaround, the use of %ifdirective can be put into an mmacro that's only called if __?NASM_IFDIRECTIVE?__ is defined. Alternatively, an %if can be used with %isdirective(...) - the %if is supported as a nested directive in the non-true conditional, despite using the unsupported %isdirective(...) I would like for this to be documented in the manual. test$ cat test1.asm %ifdef __?NASM_IFDIRECTIVE?__ %ifdirective %note %note foo %endif %endif test$ cat test2.asm %macro bar 0 %ifdirective %note %note foo %endif %endmacro %ifdef __?NASM_IFDIRECTIVE?__ bar %endif test$ cat test3.asm %ifdef __?NASM_IFDIRECTIVE?__ %if %isdirective(%note) %note foo %endif %endif test$ nasm -v NASM version 2.16.02rc2 compiled on Oct 12 2023 test$ nasm test1.asm -l /dev/stderr test1.asm:6: error: `%endif': no matching `%if' test$ nasm test2.asm -l /dev/stderr 1 %macro bar 0 2 %ifdirective %note 3 %note foo 4 %endif 5 %endmacro 6 7 %ifdef __?NASM_IFDIRECTIVE?__ 8 bar 9 %endif test$ nasm test3.asm -l /dev/stderr 1 2 %ifdef __?NASM_IFDIRECTIVE?__ 3 %if %isdirective(%note) 4 %note foo 5 %endif 6 %endif test$ ~/proj/nasmtest/broken/nasm -v NASM version 3.00rc3 compiled on Sep 9 2025 test$ ~/proj/nasmtest/broken/nasm test1.asm -l /dev/stderr 1 2 %ifdef __?NASM_IFDIRECTIVE?__ 3 %ifdirective %note 4 %note foo 4 ------------------ note: foo 5 %endif 6 %endif test$ ~/proj/nasmtest/broken/nasm test2.asm -l /dev/stderr 1 %macro bar 0 2 %ifdirective %note 3 %note foo 4 %endif 5 %endmacro 6 7 %ifdef __?NASM_IFDIRECTIVE?__ 8 bar 2 <1> %ifdirective %note 3 <1> %note foo 3 ------------------ <1> note: foo 4 <1> %endif 9 %endif test$ ~/proj/nasmtest/broken/nasm test3.asm -l /dev/stderr 1 2 %ifdef __?NASM_IFDIRECTIVE?__ 3 %if %isdirective(%note) 4 %note foo 4 ------------------ note: foo 5 %endif 6 %endif test$
Fixed the macro name, __?NASM_HAS_IFDIRECTIVE?__ was intended. I have to admit I don't really follow your request for the documentation. Perhaps you could submit a patch? This does seem to be a general issue with new %if directives; perhaps it should be mentioned in the %if section in general, and point out that using the %is() functions would avoid that problem?
Something like this might be a good way to do it: %ifdef __?NASM_HAS_IFDIRECTIVE?__ % define has_directive(x) %isdirective(x) % define has_function(x) %isdef(x) % define has_usable(x) %isusable(x) %else % define has_directive(x) 0 % define has_function(x) 0 % define has_usable(x) 0 %endif The %else clause could perhaps get further refined, but the complexity runs away pretty quickly.
> This does seem to be a general issue with new %if directives; perhaps it > should be mentioned in the %if section in general, and point out that using > the %is() functions would avoid that problem? Yes, exactly like that. I imagined putting this with the documentation of either %ifdirective or __?NASM_HAS_IFDIRECTIVE?__ but it would fit with %if generally too. Your % define has_directive(x) %isdirective(x) workaround can also be used, yes.
It obviously won't help the past, but I decided that going forward (especially going with the 3.xx major number :)) it is best to try to heuristically treat an unknown preprocessor directive beginning with %if or %elif as a conditional which should be balanced against %endif. It seems to be a reasonable thing to do.
Yes, that's a good idea too.
Found another workaround: Use an %elifdirective. It won't be detected as a conditional directive by older NASM but the %if... to %endif ratio is preserved. test$ cat test2.asm %ifdef __?NASM_HAS_IFDIRECTIVE?__ %if 0 %elifdirective %note %note quux %endif %endif test$ nasm -v NASM version 2.16.02rc2 compiled on Oct 12 2023 test$ nasm test2.asm -l /dev/stderr 1 %ifdef __?NASM_HAS_IFDIRECTIVE?__ 2 %if 0 3 %elifdirective %note 4 %note quux 5 %endif 6 %endif test$ ~/proj/nasmtest/broken/nasm -v NASM version 3.00rc4 compiled on Sep 14 2025 test$ ~/proj/nasmtest/broken/nasm test2.asm -l /dev/stderr 1 %ifdef __?NASM_HAS_IFDIRECTIVE?__ 2 %if 0 3 %elifdirective %note 4 %note quux 4 ------------------ note: quux 5 %endif 6 %endif test$
Well, I did my best and wrote some documentation.